# frozen_string_literal: true

require_relative '../../../spec_helper'
require 'base64'

describe Wpxf::Payload do
  let(:subject) { Wpxf::Payload.new }

  describe '#new' do
    it 'registers the encode_payload option' do
      expect(subject.get_option('encode_payload')).to_not be_nil
    end
  end

  describe '#encoded' do
    context 'when the encode_payload option is set to true' do
      it 'returns a base64 copy of the payload with the preamble included, wrapped in an eval call' do
        allow(subject).to receive(:php_preamble).and_return '/* preamble */'
        subject.set_option_value('encode_payload', true)
        subject.raw = 'echo "hello world";'
        expect(subject.encoded).to eq(
          '<?php eval(base64_decode(\'LyogcHJlYW1ibGUgKi8gZWNobyAiaGVsbG8gd29ybGQiOw==\')); ?>'
        )
      end
    end

    context 'when the encode_payload option is set to false' do
      it 'returns the raw payload wrapped in php tags with the preamble included' do
        allow(subject).to receive(:php_preamble).and_return '/* preamble */'
        subject.set_option_value('encode_payload', false)
        subject.raw = 'echo "hello world";'
        expect(subject.encoded).to eq '<?php /* preamble */ echo "hello world"; ?>'
      end
    end
  end

  describe '#php_preamble' do
    it 'returns the contents of the php/preamble.php data file' do
      preamble = Wpxf::DataFile.new('php', 'preamble.php').php_content
      expect(subject.php_preamble).to eq preamble
    end

    it 'creates variable assignments for each value in #constants' do
      consts = { 'const_a' => 'val_a', 'const_b' => true }
      allow(subject).to receive(:constants).and_return consts
      preamble = subject.php_preamble
      expect(preamble).to match(/\$const_a = 'val_a';/i)
      expect(preamble).to match(/\$const_b = true/i)
    end
  end

  describe '#obfuscated_variables' do
    it 'returns the variable names that should be obfuscated' do
      expect(subject.obfuscated_variables).to eq ['wpxf_disabled', 'wpxf_output', 'wpxf_exec', 'wpxf_cmd', 'wpxf_handle', 'wpxf_pipes', 'wpxf_fp']
    end
  end

  describe '#constants' do
    it 'returns a blank hash unless implemented by a child-class' do
      expect(subject.constants).to be_empty
    end
  end

  describe '#escape_single_quotes' do
    it 'returns the string with single quotes escaped' do
      expect(subject.escape_single_quotes("'test'")).to eq '\\\'test\\\''
    end
  end

  describe '#random_var_name' do
    it 'returns a random variable name' do
      expect(subject.random_var_name).to match(/[a-z]{5,20}/i)
    end
  end

  describe '#generate_vars' do
    it 'generates random variable names for each key specified' do
      res = subject.generate_vars [:a, :b, :c]
      expect(res[:a]).to match(/[a-z]{5,20}/i)
      expect(res[:b]).to match(/[a-z]{5,20}/i)
      expect(res[:c]).to match(/[a-z]{5,20}/i)
    end
  end
end
